#!/usr/bin/env python
# -*- coding: utf-8 -*-

# This project is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This project is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with Tutoo Installer.  If not, see <http://www.gnu.org/licenses/>.


from main_windows import *
from processor import *
from is_new import *
from ip_new import *
from save_changes import *
from option_frame import *
from warning_frame import *
from warning_label_frame import *
from PyQt4 import QtGui, QtCore
import os
import time

bound = {'x1': 125, 'x2':723, 'y1': 15, 'y2':522}

class Main_Project(QtGui.QMainWindow):
	def __init__(self, parent=None):
		QtGui.QMainWindow.__init__(self, parent) if parent else QtGui.QMainWindow.__init__(self)
		self.ui = Ui_MainWindow()
		self.ui.setupUi(self)

		self.warning = Warning_Message(parent=self)

		# Init of main window
		self.ui.progressBar.setGeometry(QtCore.QRect(10, 502, 640, 0))
		self.ui.progressBar.setMaximum(100)
		self.ui.progressBar.setMinimum(0)
		self.ui.progressBar.setValue(0)
		self.ui.close_button.hide()

		self.ui.proc_frame.setGeometry(QtCore.QRect(3,2,660, 0))
		self.ui.is_frame.setGeometry(QtCore.QRect(3,2,660, 0))
		self.ui.ip_frame.setGeometry(QtCore.QRect(3,2,660, 0))
		self.atual_frame = self.ui.proc_frame
		self.ui.is_frame.hide()
		self.ui.ip_frame.hide()

		self.n_objs = {'proc':0, 'is':0, 'ip':0}
		self.objects = []
		self.links = {}

		self.pos = {'x':0, 'y':0}
		self.cpos = {'x':0, 'y':0}

		self.move = None
		self.line = None
		self.setMouseTracking(True)
		self._read_config_file()

	def new_processor(self):
		new = Processor(self.ui, self.n_objs['proc'])
		new.set_proc_type(self.ui.proc_type.currentText())
		self.objects.insert(0, new)
		self.n_objs['proc'] += 1
		self.move = None
		self.warning.add_warning("Create a new processor")
		self.repaint()

	def new_is(self):
		new = Is_New(self.ui, self.n_objs['is'])
		new.set_is_type('ac_tlm_router')
		self.objects.insert(0, new)
		self.n_objs['is'] += 1
		self.move = None
		self.warning.add_warning("Create a new is")
		self.repaint()

	def new_ip(self):
		new = Ip_New(self.ui, self.n_objs['ip'])
		new.set_ip_type(self.ui.ip_type.currentText())
		self.objects.insert(0, new)
		self.n_objs['ip'] += 1
		self.move = None
		self.warning.add_warning("Create a new ip")
		self.repaint()

	def delete_object(self):
		self.n_objs[self.move.get_type()] -= 1
		self.objects.remove(self.move)
		for i in self.move.get_start_links():
			self.links.pop("%s:%s" % (self.move.get_name(), i.get_name()))
			i.remove_end_link(self.move)
		for i in self.move.get_end_links():
			self.links.pop("%s:%s" % (i.get_name(), self.move.get_name()))
			i.remove_start_link(self.move)
		self.warning.add_warning("Remove %s" % self.move.get_name())
		self.move.destroy()
		self.move = None
		self.repaint()

	def _read_config_file(self):
		""" Read configuration """
		self.config = None
		if os.path.isfile(config_file):
			f = open(config_file)
			# Remove '\n'
			self.config = map(lambda x: x.replace('\n', ''), f.readlines())
			f.close()
			for i in self.config:
				attr, value = i.split('=')
				setattr(self, attr, value)

			if hasattr(self,'arp_path'):
				print 'setting proc and ip options'
				self.ui.proc_type.clear()
				self.ui.ip_type.clear()
				if os.path.isdir(self.arp_path + 'processors'):
					for proc in os.listdir(self.arp_path + 'processors'):
						self.ui.proc_type.addItem(proc)
				if os.path.isdir(self.arp_path + 'ip'):
					for ip in os.listdir(self.arp_path + 'ip'):
						self.ui.ip_type.addItem(ip)

			return True
		return False


	def get_object(self, x, y):
		for obj in self.objects:
			if obj.inside(x, y):
				return obj
		return None

	def set_line(self, obj1, obj2):
		line = QtCore.QLine(obj1.get_center()['x'],
							obj1.get_center()['y'],
							obj2.get_center()['x'],
							obj2.get_center()['y'])

		exec('self.links["%s:%s"] = %s' % (obj1.get_name(), obj2.get_name(), str(line).replace('PyQt4.','')))
		self.repaint()


	def mousePressEvent(self, me):
		self.pos['x'] = me.pos().x()
		self.pos['y'] = me.pos().y()

		self.move = self.get_object(self.pos['x'], self.pos['y'])
		self.ui.progressBar.setGeometry(QtCore.QRect(10, 502, 640, 0))
		self.ui.progressBar.setValue(0)

		if self.move:
			self.cpos = self.move.get_center()
			link = ''
			for i in self.move.get_start_links():
				link += i.get_name() + ', '

			select_type = self.move.get_type()
			self.atual_frame.hide()
			self.atual_frame = None
			eval('self.ui.%s_frame.show()' % select_type)
			eval("self.ui.%s_name.setText(self.move.get_name() if self.move else '')" % select_type)
			eval('self.ui.%s_linked.setText(link)' % select_type)
			exec('self.atual_frame = self.ui.%s_frame' % select_type)

			if select_type == 'proc':
				n = self.ui.proc_type.findText(self.move.get_proc_type())
				self.ui.proc_type.setCurrentIndex(n)
			elif select_type == 'ip':
				n = self.ui.ip_type.findText(self.move.get_ip_type())
				self.ui.ip_type.setCurrentIndex(n)
				self.ui.ip_spin_start.setValue(self.move.get_start())
				self.ui.ip_spin_size.setValue(self.move.get_size())
		self.repaint()

	def mouseReleaseEvent(self, me):
		#if link_box is checked, update line or create a new one 
		if self.ui.link_box.checkState():
			obj1 = self.get_object(self.pos['x'], self.pos['y'])
			obj2 = self.get_object(me.pos().x(), me.pos().y())
			if obj1 and obj2 and obj1 != obj2:
				t1 = obj1.get_type()
				t2 = obj2.get_type()
				if t1 == 'proc' and t2 != 'proc' or\
					t1 == 'is' and t2 != 'is' and t2 != 'proc' or\
					t1 == 'ip' and t2 != 'ip' and t2 != 'is' and t2 != 'proc':

					obj1.start_link(obj2)
					obj2.end_link(obj1)
					self.set_line(obj1, obj2)

				else:
					w = Warning_Label(self)
					w.warning("Wrong Link!!!")
					w.exec_()
		self.line = None
		self.repaint()

	def mouseMoveEvent(self, me):
		x = me.pos().x()
		y = me.pos().y()

		move_x = x - self.pos['x']
		move_y = y - self.pos['y']

		if self.ui.link_box.checkState() and (self.move or self.line):
			self.line = QtCore.QLine(self.cpos['x'], self.cpos['y'], x, y)

		if self.move and not self.ui.link_box.checkState():
			if 	self.move.get_pos()['x'] + move_x < bound['x1'] or\
				self.move.get_pos()['y'] + move_y < bound['y1'] or\
				self.move.get_pos()['x'] + move_x > bound['x2'] or\
				self.move.get_pos()['y'] + move_y > bound['y2']:
				return

			self.move.move(move_x, move_y)
			self.pos['x'] = x
			self.pos['y'] = y

			for obj in self.move.get_start_links():
				self.set_line(self.move, obj)

			for obj in self.move.get_end_links():
				self.set_line(obj, self.move)
		self.repaint()

	def paintEvent(self, qe):
		painter = QtGui.QPainter(self)
		pen = QtGui.QPen(QtGui.QColor(0,0,0), 3)
		painter.setPen(pen)

		if self.line:
			painter.drawLine(self.line)

		for line in self.links.values():
			painter.drawLine(line)

		if self.move and not self.ui.link_box.checkState():
			pen = QtGui.QPen(QtGui.QColor(0,0,0), 1)
			pen.setDashPattern([2, 3, 2, 3])
			painter.setPen(pen)
			for line in self.move.set_selected():
				painter.drawLine(line)

	def save(self):
		self.check()
		self.warning.finish_message()
		self.warning.exec_()
		save_files = Save_Changes(self.objects, self.n_objs)
		save_files.run()
		self.ui.progressBar.setGeometry(QtCore.QRect(10, 502, 640, 41))
		self.ui.progressBar.setValue(100)
		print 'Saving project'

	def check(self):
		have_counter = False
		print self.n_objs
		if self.n_objs['proc'] == 0:
			self.warning.add_warning("No processor, it can be a problem.\nThe example software won't be work")
		if self.n_objs['is'] == 0:
			self.warning.add_warning("No is component, it can be a problem.\nThe example software won't be work")
		if self.n_objs['ip'] == 0:
			self.warning.add_warning("No ip component, it can be a problem.\nThe example software won't be work")

		for i in self.objects:
			if i.get_start_links() == [] and (i.get_type() == 'proc' or i.get_type() == 'is'):
				self.warning.add_warning('No link out %s. It, probably, is a error.' % i.get_name())
			if i.get_end_links() == [] and (i.get_type() == 'is' or i.get_type() == 'ip'):
				self.warning.add_warning('No link in %s. It, probably, is a error' % i.get_name())
			if i.get_type() == 'ip' and i.get_ip_type() == 'count':
				have_counter = True
		if not have_counter:
			self.warning.add_warning("Haven't count ip type.\nThe example software won't be work")

	def details(self):
		self.ui.details_button.hide()
		self.ui.close_button.show()
		for i in range(123):
			self.ui.proc_frame.setGeometry(QtCore.QRect(3,2,660,i))
			self.ui.is_frame.setGeometry(QtCore.QRect(3,2,660,i))
			self.ui.ip_frame.setGeometry(QtCore.QRect(3,2,660,i))

	def nodetails(self):
		self.ui.details_button.show()
		self.ui.close_button.hide()
		for i in range(123, 0, -1):
			self.ui.proc_frame.setGeometry(QtCore.QRect(3,2,660, i))
			self.ui.is_frame.setGeometry(QtCore.QRect(3,2,660, i))
			self.ui.ip_frame.setGeometry(QtCore.QRect(3,2,660, i))

	def editLineChange(self):
		if self.move:
			eval('self.move.set_name(self.ui.%s_name.text())' % self.move.get_type())

	def set_option(self):
		opt = Option_Frame(self)
		opt.exec_()
		self._read_config_file()

	def set_types(self, text):
		if self.move:
			eval('self.move.set_%s_type("%s")' % (self.move.get_type(), str(text)))

	def set_ip_start(self, start):
		if self.move:
			self.move.set_start(start)

	def set_ip_size(self, size):
		if self.move:
			self.move.set_size(size)

if __name__ == "__main__":
	import sys
	app = QtGui.QApplication(sys.argv)
	ui = Main_Project()
	ui.show()
	app.exec_()
